package cn.lei.netty.herostory.async;

import cn.lei.netty.herostory.MainMsgProcessor;

import java.text.MessageFormat;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 异步操作处理器
 *
 * @author lei
 */
public class AsyncOperationProcessor {

    /**
     * 单例对象
     */
    static private final AsyncOperationProcessor INSTANCE = new AsyncOperationProcessor();

    /**
     * 单线程数组
     */
    private final ExecutorService[] esArray = new ExecutorService[8];

    /**
     * 私有化默认构造器
     */
    private AsyncOperationProcessor() {
        for (int i = 0; i < esArray.length; i++) {
            // 线程名称
            final String threadName = MessageFormat.format("AsyncOperationProcessor[ {0} ]", i);
            esArray[i] = Executors.newSingleThreadExecutor((newRunnable) -> {
                Thread newThread = new Thread(newRunnable);
                newThread.setName(threadName);
                return newThread;
            });
        }
    }

    /**
     * 获取单例对象
     *
     * @return 单例对象
     */
    static public AsyncOperationProcessor getInstance() {
        return INSTANCE;
    }

    /**
     * 执行异步操作
     */
    public void process(IAsyncOperation op) {
        if (op == null) {
            return;
        }

        int bindId = Math.abs(op.getBindId());
        int esIndex = bindId % esArray.length;

        esArray[esIndex].submit(() -> {
            //执行异步操作
            op.doAsync();

            //回到主线程执行完成逻辑
            MainMsgProcessor.getInstance().process(op::doFinish);
        });
    }

}
